﻿using DataMonitor_Tools.Tools;
using DataMonitor_Tools.Tools.SMTP;
using DataMonitorMysql.MappingClass;
using DataMonitorWebApi.Utility;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Logging;
using Quartz;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DataMonitorWebApi.Quartz
{
    public class MyJobforLog : IJob
    {
        private readonly ILogger<MyJobforLog> _logger;
        private readonly IMemoryCache _memoryCache;//内存缓存
        private readonly IHubContext<SiginalrHub> _hubContext;//signalr
        public MyJobforLog(ILogger<MyJobforLog> logger, IMemoryCache memoryCache, IHubContext<SiginalrHub> hubContext)
        {
            _logger = logger;
            _memoryCache = memoryCache;
            _hubContext = hubContext;
        }
        public async Task Execute(IJobExecutionContext context)
        {
            var map = context.JobDetail.JobDataMap;
            string? logpath = map.GetString("logpath");
            if(logpath != null)
            {
                Console.WriteLine($"{logpath} in {Thread.CurrentThread.ManagedThreadId} run at {DateTime.Now}");
                var userprop = _memoryCache.Get<dm_props_user>(logpath);
                var adminprop = _memoryCache.Get<dm_props_admin>("datamonitoradminpara");
                //获得最新的log文件
                var file = FileOperator.GetLatestextFiles(logpath, "*.log").LastOrDefault();
                //获得缓存里的文件名
                var lastfilename = _memoryCache.Get<string>(logpath + "logname");
                //比较最新产生的文件名是否跟缓存里的一样，一样说明没有新文件产生
                if (file != null)
                {
                    if (file.Name != lastfilename)
                    {
                        if (userprop != null && adminprop != null)
                        {
                            //最新文件名存入缓存中
                            await Console.Out.WriteLineAsync($"监控到新文件{file.Name}");
                            _memoryCache.Set<string>(logpath + "logname", file.Name);
                            string[] contents = await File.ReadAllLinesAsync(file.FullName);
                            var keywords = adminprop.logkeywords.Split(";");

                            var res = SMTPWarnContent.CreateWarnContentforLog(contents, keywords, userprop.can0,userprop.idcount, file.Name);
                            #region 开始发送数据
                            if (res != "")
                            {
                                _logger.LogError(res);
                                foreach (var i in SiginalrHub.user)
                                {
                                    await _hubContext.Clients.Group(i).SendAsync("loginfo", userprop.logpath, res);
                                }
                                //先获得mailconfig缓存
                                var mailconfig = _memoryCache.Get<SMTPConfig>(userprop.vehicle + "mailconfig");
                                if (mailconfig != null && mailconfig.toemail.Contains("@"))
                                {
                                    //再从缓存里看有没有mailerror，如果没有说明第一次碰到error
                                    var firstmailerror = _memoryCache.Get<string>(userprop.vehicle + "logerror");
                                    if (firstmailerror == null)
                                    {
                                        //第一次碰到错误发送邮件
                                        await SMTPMail.SendEmailAsync(mailconfig, res);
                                        //如果第一次碰到，则创建缓存并设置为第一次的错误信息
                                        var mailerror = _memoryCache.GetOrCreate<string>(userprop.vehicle + "logerror", value =>
                                        {
                                            return res;
                                        });
                                        //再创建缓存记录第一次发送的时间
                                        var starttime = _memoryCache.GetOrCreate<DateTime>(userprop.vehicle + "logsendtime", value =>
                                        {
                                            return DateTime.Now;
                                        });
                                    }
                                    //说明缓存里已经有mailerror了，不是第一次出现问题了
                                    else
                                    {
                                        //判断当前的与上一次的是否问题一致，不一致再发邮件，再覆盖记录发送时间
                                        if (res != firstmailerror)
                                        {
                                            _memoryCache.Set<string>(userprop.vehicle + "logerror", res);
                                            await SMTPMail.SendEmailAsync(mailconfig, res);
                                            _memoryCache.Set<DateTime>(userprop.vehicle + "logsendtime", DateTime.Now);
                                        }
                                        //如果一致，则判断是否经过了1小时，然后再发送邮件提醒
                                        else
                                        {
                                            //先获取上一次缓存里的发送时间
                                            var lastsendtime = _memoryCache.Get<DateTime>(userprop.vehicle + "logsendtime");
                                            if (SMTPWarnContent.IsPastOneHour(lastsendtime, mailconfig.emailtimespan))
                                            {
                                                await SMTPMail.SendEmailAsync(mailconfig, res);
                                                _memoryCache.Set<DateTime>(userprop.vehicle + "logsendtime", DateTime.Now);
                                            }
                                        }
                                    }
                                }

                            }

                            #endregion
                        }

                    }
                }
            }
        }
    }
}
